package Classes;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.StringTokenizer;

import Interfaces.iSuperNode;

public class SuperNode extends UnicastRemoteObject implements iSuperNode{

	private static final long serialVersionUID = 1L;
	private ArrayList<Usuarios> users = null;
	private String service = "rmi://localhost:9000/SuperNode";

	public SuperNode ( ) throws RemoteException {}

	public boolean doLogin(Usuarios u) throws RemoteException {
		System.out.println("Voce, "+u.getNome()+" esta tentando logar (ass: SuperNode).");
		for (Usuarios uAux : getUsersRegistereds()) {
			if (u.getNome().equals(uAux.getNome())){
				if (u.getPass().equals(uAux.getPass())){
					uAux.setStatus(true);
					uAux.setIP(u.getIP());
					send2Group("1;"+uAux.getNome()+";"+u.getIP());
					return true;
				}
				else break;
			}
		}
		return false;
	}

	public boolean doLogout(Usuarios u) throws RemoteException {
		System.out.println("Voce, "+u.getNome()+" esta fazendo logout (ass: SuperNode).");
		for (Usuarios uAux : getUsersRegistereds()) {
			System.out.println("Percorrendo lista de usuarios para logout: "+uAux.getNome());
			if (u.getNome().equals(uAux.getNome())){
				uAux.setStatus(false);
				send2Group("0;"+uAux.getNome()+";"+u.getIP());
				System.out.println("Logout OK para " + u.getNome());
				
				return true;
			}	
		}
		return false;
	}

	public ArrayList<Usuarios> getUsersRegistereds() throws RemoteException {
		return this.users;
	}

	public static void main(String[] args) {
		try
		{
			SuperNode server = new SuperNode( );
			int portini = 4540;
			ArrayList<Usuarios> al= new ArrayList<Usuarios>();

			try {
		        BufferedReader in = new BufferedReader(new FileReader("usuarios.txt"));
		            String str;
		            while (in.ready()) {
		                str = in.readLine();
		                StringTokenizer ST = new StringTokenizer( str , ";");
		                al.add(new Usuarios(ST.nextToken(), ST.nextToken(), false, ++portini));
		            }
		            in.close();
		    } catch (IOException e) {
		    	e.printStackTrace();
		    }
			
			server.setUsers(al);
			System.out.println("SuperNode criado com sucesso!");
			LocateRegistry.createRegistry( 9000 );
			Naming.bind( server.getService() , server );
			System.out.println(server.getService());

			for (Usuarios u : server.getUsersRegistereds()) {
				System.out.println(u.getNome()+" - "+u.getPass()+" - "+u.getUDPport()+" - "+u.isStatus());
			}
		}
		catch ( Exception e )
		{
			System.out.println("Probably there is already a server running or the port is busy!");
		}
	}

	public void setUsers(ArrayList<Usuarios> users) throws RemoteException {
		this.users = users;
	}


	public String getService() throws RemoteException {
		return service;
	}

	public void setService(String service) throws RemoteException {
		this.service = service;
	}

	public void send2Group(String msg){
		try {
			InetAddress grupo = InetAddress.getByName("224.0.0.1");
			MulticastSocket s = new MulticastSocket();
			
			DatagramPacket datagram = 
				new DatagramPacket(msg.getBytes(), msg.length(),grupo, 2000);
			
			System.out.println("==> Enviando mensagem para o grupo: " + msg );
			s.send(datagram);
			System.out.println("==> Ok. send2group Finalizou!");
			
			s.close();
			
		} catch (UnknownHostException e) {
			System.err.println("Excessao causada pelo GRUPO...");
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("Excessao causada pelo Multicast...");
			e.printStackTrace();
		} catch(Exception exc) {
			exc.printStackTrace();
		}
	}

}
